package org.footballmanager.pandafootball.system.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.system.domain.FootClub;
import org.footballmanager.pandafootball.system.domain.FootCupbm;
import org.footballmanager.pandafootball.system.service.FootClubService;
import org.footballmanager.pandafootball.system.service.FootCupbfService;
import org.footballmanager.pandafootball.system.service.FootCupbmService;
import org.footballmanager.pandafootball.system.service.FootSjService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
@Service
public class FootCupbmServiceImpl extends ServiceImpl<FootCupbm> implements FootCupbmService {
	private static final String DZNUM = "dznum";
	@Autowired
	private FootSjService footSjService;
	@Autowired
	private FootClubService footClubService;
	@Autowired
	private FootCupbfService footCupbfService;
	
    @Override
	public void endCupGames(int times, HttpServletRequest request) {
		//添加16强报分记录
		footCupbfService.createBf(times, true, request);
		//添加32强报分记录
		footCupbfService.createBf(times, false, request);
	}

    @Override
	public FootCupbm findCupbmByUserid(Long userId) {
        Example example = new Example(FootCupbm.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
	    criteria.andEqualTo(Constants.USERID, userId);
		return this.findByExample(example);
	}

    @Override
	public List<FootCupbm> findList(Long sj, boolean type, int staff) {
        Example example = new Example(FootCupbm.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", sj);
	    criteria.andEqualTo("type", type);
	    criteria.andNotEqualTo(DZNUM, 0);
	    example.orderBy("dznum asc");
		List<FootCupbm> list = this.findall(example);
		List<FootCupbm> newList = new ArrayList<>();
		if(list == null || list.isEmpty()) {
            return list;
        }
		processSwitch(staff, list, newList);
		return newList;
	}

	private void processSwitch(int staff, List<FootCupbm> list, List<FootCupbm> newList){
		if(staff == 16){
			newList.addAll(list);
		}else if(staff == 8){
			processStaff8(list, newList);
		}else if(staff == 4){
			processStaff4(list, newList);
		}else if(staff == 2){
			processStaff2(list, newList);
		}else if(staff == 1){
			processStaff1(list, newList);
		}
	}

	private void processStaff8(List<FootCupbm> list, List<FootCupbm> newList){
		for(int i = 0; i < list.size(); i = i + 2){
			boolean isAdd = false;
			for(int j = 0; j < 2; j++){
				FootCupbm fc = list.get(i + j);
				if(fc.getJj1()) {
					newList.add(fc);
					isAdd = true;
				}
			}
			if(!isAdd) {
				newList.add(new FootCupbm());
			}
		}
	}

	private void processStaff4(List<FootCupbm> list, List<FootCupbm> newList){
		for(int i = 0; i < list.size(); i = i + 4){
			boolean isAdd = false;
			for(int j = 0; j < 4; j++){
				FootCupbm fc = list.get(i + j);
				if(fc.getJj2()) {
					newList.add(fc);
					isAdd = true;
				}
			}
			if(!isAdd) {
				newList.add(new FootCupbm());
			}
		}
	}

	private void processStaff2(List<FootCupbm> list, List<FootCupbm> newList){
		for(int i = 0; i < list.size(); i = i + 8){
			boolean isAdd = false;
			for(int j = 0; j < 8; j++){
				FootCupbm fc = list.get(i + j);
				if(fc.getJj3()) {
					newList.add(fc);
					isAdd = true;
				}
			}
			if(!isAdd) {
				newList.add(new FootCupbm());
			}
		}
	}

	private void processStaff1(List<FootCupbm> list, List<FootCupbm> newList){
		for(FootCupbm fc: list){
			if(fc.getJj4()){
				newList.add(fc);
			}
		}
	}

    @Override
	public void addTeam2Table(HttpServletRequest request) {
		//获取常规赛的名次，并报名杯赛
		LinkedList<FootCupbm> link16 = new LinkedList<>();
		LinkedList<FootCupbm> link32 = new LinkedList<>();
		List<FootClub> list = footClubService.getScoreboard(false, footSjService.getSj());
		if(null != list && !list.isEmpty()){
			for(int i = 0; i < 16; i++){
				if(i >= list.size()){
					link16.add(i, saveBmInfo(i, null, true, request));
				}else{
					link16.add(i, saveBmInfo(i, list.get(i).getUserId(), true, request));
				}
			}
			randomSortBmList(link16, request);
			for(int i = 16; i < 32; i++){
				if(i >= list.size()){
					link32.add(i - 16, saveBmInfo(i - 16, null, false, request));
				}else{
					link32.add(i - 16, saveBmInfo(i - 16, list.get(i).getUserId(), false, request));
				}
			}
			randomSortBmList(link32, request);
		}
	}
	
	/**
	 * 随机打乱对阵顺序
	 * @param temp 报名链表
     * @param  request 请求
	 */
	private void randomSortBmList(LinkedList<FootCupbm> temp, HttpServletRequest request){
		//取数
		Random rand = new Random();
		for(int i = 0; i < 16; i++){
			int num;
			if((temp.size() - 1) == 0){
				num = 0;
			}else{
				num = rand.nextInt(temp.size() - 1);
			}
			FootCupbm fc = temp.get(num);
			fc.setDznum(i + 1);
			this.updateNotNull(fc, request);
			temp.remove(num);
		}
	}

	/**
	 * 保存新的杯赛到数据库
	 * @param num 数量
	 * @param userId 用户主键
	 * @param type true 冠军杯 false 联盟杯
     * @param request 请求
	 * @return 报名信息
	 */
	private FootCupbm saveBmInfo(int num, Long userId, boolean type, HttpServletRequest request){
		FootCupbm bm = new FootCupbm();
		bm.setDznum(num);
		bm.setJoinDate(new Date());
		bm.setSj(footSjService.getSj());
		bm.setUserId(userId);
		bm.setType(type);
		this.save(bm, request);
		return bm;
	}

	@Override
	public FootCupbm getTop1(boolean type) {
        Example example = new Example(FootCupbm.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
        criteria.andEqualTo("type", type);
	    criteria.andNotEqualTo(DZNUM, 0);
	    criteria.andEqualTo("jj4", true);
		return this.findByExample(example);
	}

	/**
	 * 根据比赛类型和赛季主键获取报名信息列表
	 *
	 * @param type 比赛类型
	 * @param sjId 赛季主键
	 * @return 报名信息列表
	 */
	@Override
	public List<FootCupbm> findByTypeAndSj(Boolean type, Long sjId) {
		Example example = new Example(FootCupbm.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("type", type);
		criteria.andNotEqualTo(DZNUM, 0);
		criteria.andEqualTo("sj", footSjService.getSj());
		example.orderBy("dznum asc");
		return this.findall(example);
	}

    /**
     * 对战
     *
     * @param type 类型
     * @param map  参数
     */
    @Override
    public void bettle(boolean type, Model map) {
        Long sjid = footSjService.getSj();
        map.addAttribute("sj", footSjService.get(sjid));
        map.addAttribute("list16", this.findList(sjid, type, 16));
        map.addAttribute("list8", this.findList(sjid, type, 8));
        map.addAttribute("list4", this.findList(sjid, type, 4));
        map.addAttribute("list2", this.findList(sjid, type, 2));
        map.addAttribute("list1", this.findList(sjid, type, 1));

        map.addAttribute("bflist16", footCupbfService.findBf("time1", sjid, type));
        map.addAttribute("bflist8", footCupbfService.findBf("time2", sjid, type));
        map.addAttribute("bflist4", footCupbfService.findBf("time3", sjid, type));
        map.addAttribute("bflist2", footCupbfService.findBf("time4", sjid, type));
        map.addAttribute("title", type ? "冠军杯" : "联盟杯");
    }
}
